bitkeeper revision 1.1062.3.8 (40f3a5e6oIo_7nbVBKSWPEnF6B7OpQ)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Tue, 13 Jul 2004 09:05:42 +0000 (09:05 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Tue, 13 Jul 2004 09:05:42 +0000 (09:05 +0000)
Tidy up client api. Handle deferred restore.

tools/python/xen/xend/XendClient.py
tools/python/xen/xend/server/SrvDomain.py
tools/python/xen/xend/server/SrvDomainDir.py

index 3f9c41733479d1f6c0232143d38ac5c6b31d592b..ceaf4ec98aaa4e0a3d1609f711498acfa0f4e3b7 100644 (file)
@@ -207,12 +207,12 @@ class Xend:
     def xend_node_cpu_bvt_slice_set(self, ctx_allow):
         return xend_call(self.nodeurl(),
                          {'op'      : 'cpu_bvt_slice_set',
-                          'ctx_allow'   : ctx_allow })
+                          'ctx_allow' : ctx_allow })
     
     def xend_node_cpu_fbvt_slice_set(self, ctx_allow):
         return xend_call(self.nodeurl(),
                          {'op'      : 'cpu_fbvt_slice_set',
-                          'ctx_allow'   : ctx_allow })
+                          'ctx_allow' : ctx_allow })
 
     def xend_domains(self):
         return xend_get(self.domainurl())
@@ -237,11 +237,11 @@ class Xend:
 
     def xend_domain_unpause(self, id):
         return xend_call(self.domainurl(id),
-                         {'op'      : 'unpause'})
+                         {'op'      : 'unpause' })
 
     def xend_domain_pause(self, id):
         return xend_call(self.domainurl(id),
-                         {'op'      : 'pause'})
+                         {'op'      : 'pause' })
 
     def xend_domain_shutdown(self, id, reason):
         return xend_call(self.domainurl(id),
@@ -250,22 +250,22 @@ class Xend:
 
     def xend_domain_destroy(self, id):
         return xend_call(self.domainurl(id),
-                         {'op'      : 'destroy'})
+                         {'op'      : 'destroy' })
 
     def xend_domain_save(self, id, filename):
         return xend_call(self.domainurl(id),
                          {'op'      : 'save',
-                          'file'    : filename})
+                          'file'    : filename })
 
     def xend_domain_migrate(self, id, dst):
         return xend_call(self.domainurl(id),
                          {'op'      : 'migrate',
-                          'destination': dst})
+                          'destination': dst })
 
     def xend_domain_pincpu(self, id, cpu):
         return xend_call(self.domainurl(id),
                          {'op'      : 'pincpu',
-                          'cpu'     : cpu})
+                          'cpu'     : cpu })
 
     def xend_domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
         return xend_call(self.domainurl(id),
@@ -296,12 +296,11 @@ class Xend:
         return xend_get(self.domainurl(id),
                         { 'op'      : 'vifs' })
     
-    def xend_domain_vif_ip_add(self, id, vif, ipaddr):
-        return xend_call(self.domainurl(id),
-                         {'op'      : 'vif_ip_add',
-                          'vif'     : vif,
-                          'ip'      : ipaddr })
-        
+    def xend_domain_vif(self, id, vif):
+        return xend_get(self.domainurl(id),
+                        { 'op'      : 'vif',
+                          'vif'     : vif })
+    
     def xend_domain_vbds(self, id):
         return xend_get(self.domainurl(id),
                         {'op'       : 'vbds'})
@@ -309,7 +308,7 @@ class Xend:
     def xend_domain_vbd(self, id, vbd):
         return xend_get(self.domainurl(id),
                         {'op'       : 'vbd',
-                         'vbd'      : vbd})
+                         'vbd'      : vbd })
 
     def xend_consoles(self):
         return xend_get(self.consoleurl())
@@ -329,7 +328,7 @@ class Xend:
 
     def xend_vnet_delete(self, id):
         return xend_call(self.vneturl(id),
-                         {'op': 'delete'})
+                         {'op': 'delete' })
 
     def xend_event_inject(self, sxpr):
         val = xend_call(self.eventurl(),
index 80cda0d022c19be1ba4bf35fb067eddd9ad70c58..f938a5119ac4c287edf699835e9d07bc57dbcf02 100644 (file)
@@ -1,5 +1,7 @@
 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
 
+from twisted.protocols import http
+
 from xen.xend import sxp
 from xen.xend import XendDomain
 from xen.xend import XendConsole
@@ -19,14 +21,17 @@ class SrvDomain(SrvDir):
         self.xconsole = XendConsole.instance()
 
     def op_configure(self, op, req):
-        print 'op_configure>', op, req.args
         fn = FormFn(self.xd.domain_configure,
                     [['dom', 'int'],
                      ['config', 'sxpr']])
-        val = fn(req.args, {'dom': self.dom.id})
-        #todo: may need to add ok and err callbacks.
-        return val
+        deferred = fn(req.args, {'dom': self.dom.id})
+        deferred.addErrback(self._op_configure_err, req)
+        return deferred
 
+    def _op_configure_err(self, err, req):
+        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
+        return str(err)
+        
     def op_unpause(self, op, req):
         val = self.xd.domain_unpause(self.dom.id)
         return val
@@ -40,7 +45,7 @@ class SrvDomain(SrvDir):
                     [['dom', 'int'],
                      ['reason', 'str']])
         val = fn(req.args, {'dom': self.dom.id})
-        req.setResponseCode(202)
+        req.setResponseCode(http.ACCEPTED)
         req.setHeader("Location", "%s/.." % req.prePathURL())
         return val
 
@@ -53,19 +58,40 @@ class SrvDomain(SrvDir):
         fn = FormFn(self.xd.domain_save,
                     [['dom', 'int'],
                      ['file', 'str']])
-        val = fn(req.args, {'dom': self.dom.id})
-        return val
+        deferred = fn(req.args, {'dom': self.dom.id})
+        deferred.addCallback(self._op_save_cb, req)
+        deferred.addErrback(self._op_save_err, req)
+        return deferred
 
+    def _op_save_cb(self, val, req):
+        return 0
+
+    def _op_save_err(self, err, req):
+        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
+        return str(err)
+        
     def op_migrate(self, op, req):
         fn = FormFn(self.xd.domain_migrate,
                     [['dom', 'int'],
                      ['destination', 'str']])
-        val = fn(req.args, {'dom': self.dom.id})
-        val = 0 # Some migrate id.
-        req.setResponseCode(202)
-        #req.send_header("Location", "%s/.." % self.path) # Some migrate url.
-        return val
-
+        deferred = fn(req.args, {'dom': self.dom.id})
+        deferred.addCallback(self._op_migrate_cb, req)
+        deferred.addErrback(self._op_migrate_err, req)
+        return deferred
+
+    def _op_migrate_cb(self, info, req):
+        #req.setResponseCode(http.ACCEPTED)
+        host = info.dst_host
+        port = info.dst_port
+        dom  = info.dst_dom
+        url = "http://%s:%d/xend/domain/%d" % (host, port, dom)
+        req.setHeader("Location", url)
+        return url
+
+    def _op_migrate_err(self, err, req):
+        req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err))
+        return str(err)
+        
     def op_pincpu(self, op, req):
         fn = FormFn(self.xd.domain_pincpu,
                     [['dom', 'int'],
@@ -113,40 +139,6 @@ class SrvDomain(SrvDir):
         val = fn(req.args, {'dom': self.dom.id})
         return val
 
-    def op_vif_stats(self, op, req):
-        #todo
-        fn = FormFn(self.xd.domain_vif_stats,
-                    [['dom', 'int'],
-                     ['vif', 'int']])
-        #val = fn(req.args, {'dom': self.dom.id})
-        val = 999
-        #return val
-        return val
-
-    def op_vif_ip_add(self, op, req):
-        fn = FormFn(self.xd.domain_vif_ip_add,
-                    [['dom', 'int'],
-                     ['vif', 'int'],
-                     ['ip', 'str']])
-        val = fn(req.args, {'dom': self.dom.id})
-        return val
-
-    def op_vif_scheduler_set(self, op, req):
-        fn = FormFn(self.xd.domain_vif_scheduler_set,
-                    [['dom', 'int'],
-                     ['vif', 'int'],
-                     ['bytes', 'int'],
-                     ['usecs', 'int']])
-        val = fn(req.args, {'dom': self.dom.id})
-        return val
-
-    def op_vif_scheduler_get(self, op, req):
-        fn = FormFn(self.xd.domain_vif_scheduler_set,
-                    [['dom', 'int'],
-                     ['vif', 'int']])
-        val = fn(req.args, {'dom': self.dom.id})
-        return val
-
     def op_vbds(self, op, req):
         return self.xd.domain_vbd_ls(self.dom.id)
 
@@ -178,7 +170,7 @@ class SrvDomain(SrvDir):
         
     def render_GET(self, req):
         op = req.args.get('op')
-        if op and op[0] in ['vifs', 'vif', 'vif_stats', 'vbds', 'vbd']:
+        if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd']:
             return self.perform(req)
         if self.use_sxp(req):
             req.setHeader("Content-Type", sxp.mime_type)
@@ -200,32 +192,31 @@ class SrvDomain(SrvDir):
                 req.write("<code><pre>")
                 PrettyPrint.prettyprint(self.dom.config, out=req)
                 req.write("</pre></code>")
-            req.write('<a href="%s?op=vif_stats&vif=0">vif 0 stats</a>'
-                      % req.prePathURL())
             self.form(req)
             req.write('</body></html>')
         return ''
 
     def form(self, req):
-        req.write('<form method="post" action="%s">' % req.prePathURL())
+        url = req.prePathURL()
+        req.write('<form method="post" action="%s">' % url)
         req.write('<input type="submit" name="op" value="unpause">')
         req.write('<input type="submit" name="op" value="pause">')
         req.write('<input type="submit" name="op" value="destroy">')
         req.write('</form>')
 
-        req.write('<form method="post" action="%s">' % req.prePathURL())
+        req.write('<form method="post" action="%s">' % url)
         req.write('<input type="submit" name="op" value="shutdown">')
-        req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff<br>')
-        req.write('<input type="radio" name="reason" value="halt">Halt<br>')
-        req.write('<input type="radio" name="reason" value="reboot">Reboot<br>')
+        req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff')
+        req.write('<input type="radio" name="reason" value="halt">Halt')
+        req.write('<input type="radio" name="reason" value="reboot">Reboot')
         req.write('</form>')
         
-        req.write('<form method="post" action="%s">' % req.prePathURL())
+        req.write('<form method="post" action="%s">' % url)
         req.write('<br><input type="submit" name="op" value="save">')
-        req.write('To file: <input type="text" name="file">')
+        req.write(' To file: <input type="text" name="file">')
         req.write('</form>')
         
-        req.write('<form method="post" action="%s">' % req.prePathURL())
+        req.write('<form method="post" action="%s">' % url)
         req.write('<br><input type="submit" name="op" value="migrate">')
-        req.write('To host: <input type="text" name="destination">')
+        req.write(' To host: <input type="text" name="destination">')
         req.write('</form>')
index 8ca623985002ffb1016bdfef0d933848c88bb815..4c1fd4e14fd485391fd36b76890055a9e2291689 100644 (file)
@@ -81,7 +81,7 @@ class SrvDomainDir(SrvDir):
         """
         dom = dominfo.id
         domurl = "%s/%s" % (req.prePathURL(), dom)
-        req.setResponseCode(201, "created")
+        req.setResponseCode(http.CREATED, "created")
         req.setHeader("Location", domurl)
         if self.use_sxp(req):
             return dominfo.sxpr()
@@ -111,8 +111,30 @@ class SrvDomainDir(SrvDir):
         #todo: return is deferred. May need ok and err callbacks.
         fn = FormFn(self.xd.domain_restore,
                     [['file', 'str']])
-        val = fn(req.args)
-        return val
+        deferred = fn(req.args)
+        deferred.addCallback(self._op_restore_cb, req)
+        deferred.addErrback(self._op_restore_err, req)
+        return deferred
+
+    def _op_restore_cb(self, dominfo, req):
+        dom = dominfo.id
+        domurl = "%s/%s" % (req.prePathURL(), dom)
+        req.setResponseCode(http.CREATED)
+        req.setHeader("Location", domurl)
+        if self.use_sxp(req):
+            return dominfo.sxpr()
+        else:
+            out = StringIO()
+            print >> out, ('<p> Created <a href="%s">Domain %s</a></p>'
+                           % (domurl, dom))
+            val = out.getvalue()
+            out.close()
+            return val
+
+    def _op_restore_err(self, err, req):
+        print 'op_create> Deferred Exception restoring domain:', err
+        req.setResponseCode(http.BAD_REQUEST, "Error restoring domain: "+ str(err))
+        return str(err)
         
     def render_POST(self, req):
         return self.perform(req)